﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;

namespace scavenger.winforms
{
    public partial class BandwidthMeter : Form
    {
        Thread StartTesting=null;
        Dictionary<string, string> servers = new Dictionary<string, string>();
        HttpWebRequest request = null;
        HttpWebResponse response = null;
        Stream ns = null;
        double totReadMB = 0; //in mbs
        double totReadKB = 0;
        double speed = 0; //in Kbps
        string abortMessage = "";

        public BandwidthMeter()
        {
            InitializeComponent();
        }

        private void BandwidthMeter_Load(object sender, EventArgs e)
        {
            servers.Add("IIT Kanpur (India)", "http://mirror.cse.iitk.ac.in/fedora/releases/18/Everything/x86_64/os/Packages/0/0ad-data-0.0.11-3.fc18.noarch.rpm");
            servers.Add("Debian (UK)", "http://debian-iso.mirror.anlx.net/7.0.0/i386/iso-dvd/debian-7.0.0-i386-DVD-1.iso");
            servers.Add("Debian (Indonesia)", "http://mirror.unej.ac.id/debian-cd/7.0.0/i386/iso-dvd/debian-7.0.0-i386-DVD-1.iso");
            //servers.Add("FreeBSD (Armenia)", "ftp://ftp.ee.freebsd.org/pub/FreeBSD/ISO-IMAGES-amd64/9.1/FreeBSD-9.1-RELEASE-amd64-dvd1.iso");
            servers.Add("FreeBSD (Germany)", "http://www1.de.freebsd.org/freebsd/ISO-IMAGES-ia64/9.1/FreeBSD-9.1-RELEASE-ia64-release.iso");

            foreach (KeyValuePair<string, string> kvp in servers)
            {
                cmbTestbed.Items.Add(kvp.Key);  
            }
            cmbTestbed.SelectedIndex = 0;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (button1.Text == "Start")
            {
                StartTesting = new Thread(StartTestingThread);
                StartTesting.Start(servers[cmbTestbed.Text]);
                timer1.Start();
                button1.Text = "Stop";
            }
            else 
            {
                StartTesting.Abort();
                if (abortMessage.Length > 0)
                    MessageBox.Show("Error occured: " + abortMessage, Application.ProductName);
                button1.Text = "Start";

            }
        }

        private void Reset()
        {
            if (ns != null) ns.Close(); ns = null;
            request = null;
            response = null;
            timer1.Stop();
            totReadMB = 0;
            totReadKB = 0;
            //txtReceived.Text = "0.00";
            //txtAverageSpeed.Text = "0.00";
        }

        private void StartTestingThread(object serverUrl)
        {
            try
            {
                abortMessage = "";
                if (request == null)
                {
                    string url = serverUrl.ToString();
                    //txtServer.Text = url;
                    request = (HttpWebRequest)HttpWebRequest.Create(url);
                    response = (HttpWebResponse)request.GetResponse();
                    ns = response.GetResponseStream();
                }

                int read = 0;
                byte[] buffer = new byte[4096];
                DateTime start = DateTime.Now;
                while ((read = ns.Read(buffer, 0, buffer.Length)) > 0 && button1.Text == "Stop")
                {

                    double readKB = (read / 1024.00) ;
                    totReadKB += readKB;
                    totReadMB = totReadKB/ 1024.00;
                    speed = totReadKB/DateTime.Now.Subtract(start).TotalSeconds;
                    //Application.DoEvents();
                }
            }
            catch (System.Threading.ThreadAbortException ex) 
            {
                Reset();
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.Message, Application.ProductName);
                abortMessage = ex.Message;
                Reset();
            }
        }

        private void cmbTestbed_SelectedValueChanged(object sender, EventArgs e)
        {
            string url = servers[cmbTestbed.Text];
            txtServer.Text = url;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            txtReceived.Text = String.Format("{0:0.00}", totReadMB);
            txtAverageSpeed.Text = string.Format("{0:0.00}", speed);
        }
    }
}
